﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Rally_like_a_madman.Data;
using System.Linq;
using System.Device.Location;
using System.Collections.Generic;

namespace Rally_like_a_madman
{
    public static class NavigationHelper
    {
        private static Route currentRoute;
        private static Waypoint nextWaypointOnRoute;
        private static int currentWaypointIndex;
        private static List<RouteWaypointLink> currentRouteWaypointLinks;
        private static DateTime startTime, endTime;

        public static Waypoint GetNextWaypointOnRoute()
        {
            return nextWaypointOnRoute;
        }

        /// <summary>
        /// Method used for getting all the waypoints on the current route
        /// This can't return the waypoint ID's on the route.
        /// </summary>
        /// <returns></returns>
        public static List<RouteWaypointLink> GetAllWaypointsLinksOnCurrentRoute()
        {
            return currentRouteWaypointLinks;
        }

        /// <summary>
        /// Method used for getting all RouteWaypointLinks 'connected' to a route.
        /// All waypointindexes can still be used.
        /// </summary>
        /// <param name="thisRoute"></param>
        /// <returns></returns>
        public static List<RouteWaypointLink> GetAllWaypointLinksByRoute(Route thisRoute)
        {
            List<RouteWaypointLink> routeWaypointLinks = new List<RouteWaypointLink>();

            App thisApp = Application.Current as App;

            if (thisApp == null)
                return null;

            var queryWaypointLinks = from RouteWaypointLink routeWaypointLink in thisApp.ActiveDB.RouteLinkTable
                                     select routeWaypointLink;

            List<RouteWaypointLink> queriedLinks = queryWaypointLinks.ToList() as List<RouteWaypointLink>;


            foreach(RouteWaypointLink link in queriedLinks)
            {
                if (link.Route == thisRoute)
                routeWaypointLinks.Add(link);
            }

            return routeWaypointLinks;
        }

        /// <summary>
        /// Method for going to the next waypoint on a route.
        /// Returns true if there is a next waypoint, and it's set. (route hasn't ended)
        /// Returns false if there isn't a next waypoint (route has ended)
        /// </summary>
        /// <returns></returns>
        public static bool Next()
        {
            int newIndex = currentWaypointIndex + 1;
            RouteWaypointLink deleteLink = null;
            RouteWaypointLink nextLink = null;

            //filter all links in the current route.
            foreach (RouteWaypointLink link in currentRouteWaypointLinks)
            {
                //if the index is equal to the current waypoints index, 
                //put this one up for deletion.
                if (link.WaypointIndex == currentWaypointIndex)
                    deleteLink = link;
                //if the index is equal to the next waypoints index,
                //put this one up as 'next link'
                if (link.WaypointIndex ==  newIndex)
                    nextLink = link;
            }             

            if (nextLink != null && nextLink.Waypoint != null && nextLink.WaypointIndex == newIndex /* Yes, this is a double check, better safe than sorry */ )
            {
                currentWaypointIndex = newIndex;
                currentRouteWaypointLinks.Remove(deleteLink);
                nextWaypointOnRoute = nextLink.Waypoint;
                System.Diagnostics.Debug.WriteLine("Next waypoint: " + nextWaypointOnRoute.ToString());
                return true;
            }
            else
            {
                endOfRoute();
                return false;
            }

        }

        private static void endOfRoute()
        {
            currentRouteWaypointLinks = new List<RouteWaypointLink>();
            currentWaypointIndex = 0;
            nextWaypointOnRoute = null;
        }

        /// <summary>
        /// Method for getting the current route
        /// </summary>
        /// <returns></returns>
        public static Route GetCurrentRoute()
        {
            return currentRoute;
        }

        public static DateTime GetStartTime()
        {
            return startTime;
        }

        public static void SetEndTime()
        {
            endTime = DateTime.Now;
        }

        public static DateTime GetEndTime()
        {
            return endTime;
        }

        /// <summary>
        /// Method that handles starting a route
        /// Sets all NavigationHelper values according to a new route;
        /// nextWaypointOnRoute, currentWaypointIndex, currentRouteWaypointLinks, currentRoute
        /// </summary>
        /// <param name="route"></param>
        public static bool StartRoute(Route route)
        {
            currentRoute = route;
            startTime = DateTime.Now;
            currentWaypointIndex = 0;
            currentRouteWaypointLinks = GetAllWaypointLinksByRoute(currentRoute);

            foreach(RouteWaypointLink link in currentRouteWaypointLinks)
            {
                System.Diagnostics.Debug.WriteLine(link.ToString());
            }
            Waypoint nextWaypoint = null;

            foreach (RouteWaypointLink waypointLink in currentRouteWaypointLinks)
            {
                if (waypointLink.WaypointIndex == currentWaypointIndex)
                    nextWaypoint = waypointLink.Waypoint;
            }

            if (nextWaypoint != null)
            {
                nextWaypointOnRoute = nextWaypoint;
                return true;
            }
            else
                return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="waypointName"></param>
        /// <returns></returns>
        public static bool CheckIfWaypointExists(string waypointName)
        {
            App thisApp = Application.Current as App;
            var tmpWaypoints = from Waypoint waypoint in thisApp.ActiveDB.WaypointTable select waypoint;

            List<Waypoint> existingWaypoints = tmpWaypoints.ToList() as List<Waypoint>;
            bool waypointNameExists = false;

            if (existingWaypoints != null)
            {
                foreach (Waypoint r in existingWaypoints)
                {
                    if (r.Name.ToLower() == waypointName.ToLower())
                        waypointNameExists = true;
                }

                if (waypointNameExists)
                    return true;
            }

            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="routeName"></param>
        /// <returns></returns>
        public static bool CheckIfRouteExists(string routeName)
        {
            App thisApp = Application.Current as App;
            var tmpRoutes = from Route route in thisApp.ActiveDB.RouteTable select route;

            List<Route> existingRoutes = tmpRoutes.ToList() as List<Route>;
            bool routeNameExists = false;

            if (existingRoutes != null)
            {
                foreach (Route r in existingRoutes)
                {
                    if (r.Name.ToLower() == routeName.ToLower())
                        routeNameExists = true;
                }

                if (routeNameExists)
                    return true;
            }

            return false;
        }
    }
}
